#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ESP8266WiFiMulti.h>
#include <Ticker.h>
#include <time.h>

ESP8266WiFiMulti wifiMulti;
// wifi ---------------------------------------------------------
#ifndef STASSID
#define STASSID "wifi-wjh6"
#define STAPSK "987987987"
// 测试环境 是否开启串口打印
#define SERIAL_P true //false // 
#define SERIAL_I true //false // 
#endif

const char* ssid = STASSID;
const char* password = STAPSK;

// 北京时间URL
const char* beijingTimeUrl = "https://bjtime.org.cn/bjtime.php?timeZone=8";
// 高德天气api 来自中国气象局 实况天气 每日300000次
const char* weatherUrl = "https://restapi.amap.com/v3/weather/weatherInfo?key=11792e0ede8799a1f8e67d0ac4fa96a9&city=110000&output=JSON&extensions=";

void getTimeInfo();
Ticker timer1; // 每秒回调计时器

int requestCount = 0; // 当前回调的次数
int httpCode = 0;     // 网络请求结果状态
int requestStatu = 0; // 网络请求状态

void setup() {
  // put your setup code here, to run once:
  if (SERIAL_I) {
    Serial.begin(9600);
  }
  
  initWifi();

  timer1.attach(1, refreshAction); // 每秒计数
}

void loop() {
  // put your main code here, to run repeatedly:

}

// 计时器出发的每秒计时
// 在 连接Wi-Fi成功 且 https请求成功 之后开始计数
void refreshAction() {

  if (requestCount == 0) {// 初次更新一次时间
      
      getTimeInfo();
  }
}


// 获取北京时间信息
void getTimeInfo() {
  String payload = getHttpsInfo(beijingTimeUrl);
  if (payload.length() == 0) {
    Serial.println("获取北京时间 请求失败\n\n");
    return;
  }
  // ------ 处理时间戳信息 ------
  // 定义要截取的起始位置和长度
  int start = 9; // 假设我们要开始截取的位置
  int length = 10; // 假设我们要截取的长度
  // 使用substring方法截取字符串
  String part = payload.substring(start, start + length);
  int timestamp = part.toInt();
  beijingTimestamp = timestamp;
  timestamp_to_beijing(timestamp);
  if (SERIAL_P) {
    Serial.println("获取北京时间戳：" + part);

    Serial.println();
  }

  if (SERIAL_P) {
  }
}

// 获取接口数据
// url 请求地址https
String getHttpsInfo(String url) {
  
  requestStatu = 0; // 开始请求
  String requestInfo = "http ready to connect";
  if (SERIAL_P) {
    Serial.println(">> http ready to connect");
  }
  if ((wifiMulti.run() == WL_CONNECTED)) { // 连接Wi-Fi成功

    //创建 HTTPClient 对象
    HTTPClient httpsClient;
    BearSSL::WiFiClientSecure wifiClient;

    wifiClient.setInsecure();
    if (SERIAL_P) {
        Serial.println(">> http begin request");
    }

    if ( httpsClient.begin(wifiClient, url) ) {
      if (SERIAL_P) {
        Serial.println(">> http get request：" + url);
      }
      // 启动连接并发送HTTP头
      httpCode = httpsClient.GET();
      if (SERIAL_P) {
        Serial.println(">> http get request httpCode：" + httpCode);
      }
      requestStatu = 1; // 请求完成
      if (httpCode == 200) {
        requestStatu = 200; // 请求成功
      }
      if (SERIAL_P) {
          Serial.printf(">> http get code:%d\n", httpCode);
      }

      if (httpCode > 0) {

        if (httpCode == HTTP_CODE_OK) {
          String payload = httpsClient.getString();
          
          requestInfo = payload;
        }else {

          requestInfo = "http code not ok";
        }
        if (SERIAL_P) {
          Serial.println(requestInfo);
          Serial.println(requestStatu);
          Serial.println(httpCode);
        }
        // 返回payload
        return requestInfo;
      }else {
        if (SERIAL_P) {
          Serial.printf("http get failed, error:%s\n", httpsClient.errorToString(httpCode).c_str());
          Serial.println("");
        }
      }
      httpsClient.end();
      requestStatu = 5;// 请求结束
    }else {
      requestStatu = -1;//请求失败
      if (SERIAL_P) {
        Serial.println("http unable to connect");
      }
    }
  }else {
    requestInfo = "wifi is not connected";
    requestStatu = -2; // 网络未链接
    httpCode = -2;// 网络未链接
  }
  if (SERIAL_P) {
    Serial.println("http end request info");
    Serial.println(requestInfo);
    Serial.println(requestStatu);
    Serial.println(httpCode);
  }
  return "";
}

// 初始化Wi-Fi
void initWifi() {

  if (SERIAL_P) {
    Serial.println("init wifi");
  }
  WiFi.mode(WIFI_STA);
  // Register multi WiFi networks
  wifiMulti.addAP(ssid, password);
  wifiMulti.addAP("iPhone X", "987987987");
  
  while (wifiMulti.run(connectTimeoutMs) != WL_CONNECTED) {
    delay(500);
    if (SERIAL_P) {
      Serial.println("init wifi");
    }
  }
}


// 时间戳转换北京时间
void timestamp_to_beijing(int timestamp) {
 
  timestamp += 8 * 3600 + 10; // 加上8小时的秒数（8 * 3600 = 28800）
  time_t t = timestamp;
  // 将时间戳转换为tm结构
  struct tm *timeinfo;
  timeinfo = localtime(&t);

  year = timeinfo->tm_year + 1900;
  month = timeinfo->tm_mon + 1;
  day = timeinfo->tm_mday;
  hour = timeinfo->tm_hour;
  minute = timeinfo->tm_min;
  second = timeinfo->tm_sec;
  weekday = timeinfo->tm_wday;
  if (SERIAL_P) {
    Serial.println(""); 
    Serial.print(year);
    Serial.print("-");
    Serial.print(month);
    Serial.print("-");
    Serial.print(day);
    Serial.print(" ");
    Serial.print(hour);
    Serial.print(":");
    Serial.print(minute);
    Serial.print(":");
    Serial.print(second);
  }
}

